﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ComponentModel;
using System.Collections.Generic;
using System.Collections.ObjectModel;

namespace V2TEK.NET.SH.Silverlight.Charts.Core
{
    public class LayoutUpdateEventArgs : EventArgs
    {
        public LayoutUpdateEventArgs(object _layout)
        {
            this.Layout = _layout;
        }
        public object Layout { get; set; }
    }

    public delegate void LayoutUpdate(object sender, LayoutUpdateEventArgs args);

    public abstract class Layout<T> : FrameworkElement, ILayout<T>, INotifyPropertyChanged
    {
        public const string CONTENT_HEIGHT_PROPERTY = "ContentHeight";
        public const string CONTENT_WIDTH_PROPERTY = "ContentWidth";
        public const string VIEWPORT_HEIGHT_PROPERTY = "ViewPortHeight";
        public const string VIEWPORT_WIDTH_PROPERTY = "ViewPortWidth";
        public const string XPOSITION_PROPERTY = "XPosition";
        public const string YPOSITION_PROPERTY = "YPosition";

        public static DependencyProperty ContentHeightProperty = DependencyProperty.Register(CONTENT_HEIGHT_PROPERTY, typeof(double), typeof(Layout<T>), new PropertyMetadata(0d, new PropertyChangedCallback(PropertyChangeCallBack)));
        public static DependencyProperty ContentWidthProperty = DependencyProperty.Register(CONTENT_WIDTH_PROPERTY, typeof(double), typeof(Layout<T>), new PropertyMetadata(0d,new PropertyChangedCallback(PropertyChangeCallBack)));
        public static DependencyProperty ViewPortHeightProperty = DependencyProperty.Register(VIEWPORT_HEIGHT_PROPERTY, typeof(double), typeof(Layout<T>), new PropertyMetadata(0d, new PropertyChangedCallback(PropertyChangeCallBack)));
        public static DependencyProperty ViewPortWidthProperty = DependencyProperty.Register(VIEWPORT_WIDTH_PROPERTY, typeof(double), typeof(Layout<T>), new PropertyMetadata(0d, new PropertyChangedCallback(PropertyChangeCallBack)));

        public static DependencyProperty XPositionProperty = DependencyProperty.Register(XPOSITION_PROPERTY, typeof(double), typeof(Layout<T>), new PropertyMetadata(0d, new PropertyChangedCallback(PropertyChangeCallBack)));
        public static DependencyProperty YPositionProperty = DependencyProperty.Register(YPOSITION_PROPERTY, typeof(double), typeof(Layout<T>), new PropertyMetadata(0d, new PropertyChangedCallback(PropertyChangeCallBack)));

        public event LayoutUpdate OnLayoutUpdate;

        protected static void PropertyChangeCallBack(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        {
            Layout<T> ly = (sender as Layout<T>);

            string pn = string.Empty;
            if (args.Property.Equals(ContentHeightProperty))
                pn = CONTENT_HEIGHT_PROPERTY;
            else if (args.Property.Equals(ContentWidthProperty))
            {
                ly.ContentWidthPropertyChanged(sender, args);
                pn = CONTENT_WIDTH_PROPERTY;
            }
            else if (args.Property.Equals(ViewPortHeightProperty))
                pn = VIEWPORT_HEIGHT_PROPERTY;
            else if (args.Property.Equals(ViewPortWidthProperty))
                pn = VIEWPORT_WIDTH_PROPERTY;
            else if (args.Property.Equals(XPositionProperty))
                pn = XPOSITION_PROPERTY;
            else
                pn = YPOSITION_PROPERTY;

            if (ly.PropertyChanged != null)
                ly.PropertyChanged(ly, new PropertyChangedEventArgs(pn));
        }

        protected virtual void ContentWidthPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        {
            
        }

        #region ILayout Members

        public ObservableCollection<T> Items
        {
            get;
            set;
        }

        public double ViewPortHeight
        {
            get { return (double)GetValue(ViewPortHeightProperty); }
            set { SetValue(ViewPortHeightProperty, value); }
        }

        public double ViewPortWidth
        {
            get { return (double)GetValue(ViewPortWidthProperty); }
            set
            {
                SetValue(ViewPortWidthProperty, value);
                if (PropertyChanged != null)
                    PropertyChanged(this, new PropertyChangedEventArgs("ViewPortWidth"));
            }
        }

        public double ContentHeight
        {
            get { return (double)GetValue(ContentHeightProperty); }
            set { SetValue(ContentHeightProperty, value); }
        }

        public double ContentWidth
        {
            get { return (double)GetValue(ContentWidthProperty); }
            set 
            {
                SetValue(ContentWidthProperty, value);
            }
        }

        public double XPosition
        {
            get { return (double)GetValue(XPositionProperty); }
            set 
            {
                SetValue(XPositionProperty, value);
            }
        }

        public double YPosition
        {
            get { return (double)GetValue(YPositionProperty); }
            set { SetValue(YPositionProperty, value); }
        }


        #endregion

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion


        public virtual void Update()
        {
            if (this.OnLayoutUpdate != null)
                this.OnLayoutUpdate(this, new LayoutUpdateEventArgs(this));
        }
    }
}
